package br.ufc.great.dtx.tm.sch;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Vector;

import br.ufc.great.dataguide.DGElement;
import br.ufc.great.dtx.server.DTXOutput;
import br.ufc.great.dtx.tm.AbortTransactionException;
import br.ufc.great.dtx.tm.Transaction;
import br.ufc.great.dtx.tm.deadlockdetector.RemoteWFGMessage;
import br.ufc.great.dtx.tm.deadlockdetector.WFGMessage;
import br.ufc.great.dtx.tm.lm.LockIncompatibleException;
import br.ufc.great.dtx.tm.operations.Operation;
import br.ufc.great.dtx.tm.operations.Site;

/**
 * 
 * @author Leonardo Oliveira Moreira
 *
 * Classe que implementa uma parte do escalonador que processa as requisições de grafos de espera (WFG)
 */
public class SchedulerRemoteWFGMessage extends Thread {

	private DTXOutput output;
	private Scheduler scheduler;
	
	// Lista de requisições de WFGs
	private Vector<RemoteWFGMessage> remoteWFGMessages;
	
	public SchedulerRemoteWFGMessage(DTXOutput output, Scheduler scheduler) {
		this.output = output;
		this.scheduler = scheduler;
		remoteWFGMessages = new Vector<RemoteWFGMessage>();
		setPriority(MIN_PRIORITY);
	}
	
	public void run() {
		while (isAlive()) {
			// Processa requisições de WFG
			while (remoteWFGMessages.size() > 0) {
				RemoteWFGMessage remoteWFGMessage = remoteWFGMessages.remove(0);
				//output.print(getClass().getSimpleName(), "processing request", DTXOutput.TEST);
				Socket socket = remoteWFGMessage.getSocket();
				WFGMessage wfgMessage = remoteWFGMessage.getMessage();
				wfgMessage.setGraph(scheduler.getWaitForGraph());
				try {
					ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
					out.writeObject(wfgMessage);
					out.flush();
					//output.print(getClass().getSimpleName(), "has responsed", DTXOutput.TEST);
				} catch (IOException e) {
					output.print(getClass().getSimpleName(), e.getMessage(), DTXOutput.ERROR);
				}
			}
			if (remoteWFGMessages.size() > 0)
				continue;
			pause();
		}
	}
	
	public synchronized void pause() {
		try {
			//output.print(getClass().getSimpleName(), "is waiting", DTXOutput.TEST);
			wait();
		}
		catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public synchronized void restart() {
		notify();
	}
	
	public synchronized void addRemoteWGFMessage(RemoteWFGMessage remoteWFGMessage) {
		//output.print(getClass().getSimpleName(), "Remote WFG message was received", DTXOutput.TEST);
		remoteWFGMessages.add(remoteWFGMessage);
		restart();
	}
	
	public synchronized int size() {
		return remoteWFGMessages.size();
	}
	
}
